using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using WalkingTec.Mvvm.Core;

namespace HengTong.Model.Db.Hr.Attendance.Rule
{
    /// <summary>
    /// 考勤补贴规则实体类，用于定义各种考勤相关补贴的发放规则
    /// </summary>
    /// <remarks>
    /// 支持餐补、交通补贴等多种类型的补贴规则配置，
    /// 包含生效时间、限制条件、补贴金额计算等完整功能
    /// </remarks>
    public class SysAttendanceSubsidyRule : TopBasePoco
    {
        // —— 基本信息 ——
        
        /// <summary>
        /// 获取或设置规则名称
        /// </summary>
        /// <value>补贴规则的显示名称，用于标识不同的补贴规则</value>
        [Display(Name = "规则名称", Description = "补贴规则的显示名称", GroupName = "基本信息")]
        [Required(ErrorMessage = "规则名称不能为空")]
        [MaxLength(128, ErrorMessage = "规则名称长度不能超过128个字符")]
        public string Name { get; set; }
        
        /// <summary>
        /// 获取或设置规则类型
        /// </summary>
        /// <value>补贴的类型：餐补、交通补贴、加班补贴等</value>
        [Display(Name = "规则类型", Description = "补贴的类型分类", GroupName = "基本信息")]
        [Required(ErrorMessage = "规则类型不能为空")]
        public SysSubsidyRuleType RuleType { get; set; }
        
        /// <summary>
        /// 获取或设置生效开始日期
        /// </summary>
        /// <value>规则开始生效的日期</value>
        [Display(Name = "开始日期", Description = "规则开始生效的日期", GroupName = "基本信息")]
        [DataType(DataType.Date)]
        public DateTime? EffectiveStartDate { get; set; }
        
        /// <summary>
        /// 获取或设置生效结束日期
        /// </summary>
        /// <value>规则结束生效的日期，为空表示长期有效</value>
        [Display(Name = "结束日期", Description = "规则结束生效的日期，为空表示长期有效", GroupName = "基本信息")]
        [DataType(DataType.Date)]
        public DateTime? EffectiveEndDate { get; set; }
        
        /// <summary>
        /// 获取或设置规则是否启用
        /// </summary>
        /// <value>true表示启用，false表示禁用</value>
        [Display(Name = "是否启用", Description = "规则是否生效", GroupName = "基本信息")]
        public bool IsEnabled { get; set; } = true;

        /// <summary>
        /// 获取或设置规则备注信息
        /// </summary>
        /// <value>对补贴规则的详细说明或特殊要求</value>
        [Display(Name = "备注", Description = "补贴规则的备注信息", GroupName = "基本信息")]
        [MaxLength(512, ErrorMessage = "备注长度不能超过512个字符")]
        public string Remark { get; set; }

        // —— 限制条件 ——
        
        /// <summary>
        /// 获取或设置是否启用出勤时间限制
        /// </summary>
        /// <value>true表示需要满足出勤时间条件才能获得补贴</value>
        [Display(Name = "启用出勤时间限制", Description = "是否需要满足出勤时间条件", GroupName = "限制条件")]
        public bool AttendanceTimeConditionEnabled { get; set; } = false;
        
        /// <summary>
        /// 获取或设置最小出勤时间要求
        /// </summary>
        /// <value>获得补贴所需的最少出勤小时数</value>
        [Display(Name = "最小出勤时间(小时)", Description = "获得补贴所需的最少出勤小时数", GroupName = "限制条件")]
        [Range(0, 24, ErrorMessage = "出勤时间必须在0-24小时之间")]
        [Column(TypeName = "decimal(8,2)")]
        public decimal? MinAttendanceHours { get; set; }
        
        /// <summary>
        /// 获取或设置是否启用签到时间限制
        /// </summary>
        /// <value>true表示需要在指定时间范围内签到才能获得补贴</value>
        [Display(Name = "启用签到时间限制", Description = "是否需要在指定时间范围内签到", GroupName = "限制条件")]
        public bool CheckinTimeConditionEnabled { get; set; } = false;
        
        /// <summary>
        /// 获取或设置签到时间限制开始基准日期偏移
        /// </summary>
        /// <value>签到时间限制开始时间的日期偏移</value>
        [Display(Name = "签到开始基准日", Description = "签到时间限制开始时间的日期偏移", GroupName = "限制条件")]
        public SysDayOffset CheckinStartDayOffset { get; set; } = SysDayOffset.当日;
        
        /// <summary>
        /// 获取或设置签到时间限制开始时间
        /// </summary>
        /// <value>有效签到的最早时间</value>
        [Display(Name = "签到开始时间", Description = "有效签到的最早时间", GroupName = "限制条件")]
        [DataType(DataType.Time)]
        public TimeSpan? CheckinStartTime { get; set; }
        
        /// <summary>
        /// 获取或设置签到时间限制结束基准日期偏移
        /// </summary>
        /// <value>签到时间限制结束时间的日期偏移</value>
        [Display(Name = "签到结束基准日", Description = "签到时间限制结束时间的日期偏移", GroupName = "限制条件")]
        public SysDayOffset CheckinEndDayOffset { get; set; } = SysDayOffset.当日;
        
        /// <summary>
        /// 获取或设置签到时间限制结束时间
        /// </summary>
        /// <value>有效签到的最晚时间</value>
        [Display(Name = "签到结束时间", Description = "有效签到的最晚时间", GroupName = "限制条件")]
        [DataType(DataType.Time)]
        public TimeSpan? CheckinEndTime { get; set; }
        
        /// <summary>
        /// 获取或设置是否启用签出时间限制
        /// </summary>
        /// <value>true表示需要在指定时间范围内签出才能获得补贴</value>
        [Display(Name = "启用签出时间限制", Description = "是否需要在指定时间范围内签出", GroupName = "限制条件")]
        public bool CheckoutTimeConditionEnabled { get; set; } = false;
        
        /// <summary>
        /// 获取或设置签出时间限制开始基准日期偏移
        /// </summary>
        /// <value>签出时间限制开始时间的日期偏移</value>
        [Display(Name = "签出开始基准日", Description = "签出时间限制开始时间的日期偏移", GroupName = "限制条件")]
        public SysDayOffset CheckoutStartDayOffset { get; set; } = SysDayOffset.当日;
        
        /// <summary>
        /// 获取或设置签出时间限制开始时间
        /// </summary>
        /// <value>有效签出的最早时间</value>
        [Display(Name = "签出开始时间", Description = "有效签出的最早时间", GroupName = "限制条件")]
        [DataType(DataType.Time)]
        public TimeSpan? CheckoutStartTime { get; set; }
        
        /// <summary>
        /// 获取或设置签出时间限制结束基准日期偏移
        /// </summary>
        /// <value>签出时间限制结束时间的日期偏移</value>
        [Display(Name = "签出结束基准日", Description = "签出时间限制结束时间的日期偏移", GroupName = "限制条件")]
        public SysDayOffset CheckoutEndDayOffset { get; set; } = SysDayOffset.当日;
        
        /// <summary>
        /// 获取或设置签出时间限制结束时间
        /// </summary>
        /// <value>有效签出的最晚时间</value>
        [Display(Name = "签出结束时间", Description = "有效签出的最晚时间", GroupName = "限制条件")]
        [DataType(DataType.Time)]
        public TimeSpan? CheckoutEndTime { get; set; }

        // —— 补贴金额 ——
        
        /// <summary>
        /// 获取或设置补贴计算方式
        /// </summary>
        /// <value>补贴金额的计算方式：固定金额或按公式计算</value>
        [Display(Name = "计算方式", Description = "补贴金额的计算方式", GroupName = "补贴金额")]
        [Required(ErrorMessage = "计算方式不能为空")]
        public SysSubsidyCalculationType CalculationType { get; set; } = SysSubsidyCalculationType.固定金额;
        
        /// <summary>
        /// 获取或设置固定补贴金额
        /// </summary>
        /// <value>固定的补贴金额，当计算方式为固定金额时使用</value>
        [Display(Name = "固定金额", Description = "固定的补贴金额", GroupName = "补贴金额")]
        [Range(typeof(decimal), "0", "999999", ErrorMessage = "固定金额必须在0-999999之间")]
        [Column(TypeName = "decimal(8,2)")]
        public decimal? FixedAmount { get; set; }
        
        /// <summary>
        /// 获取或设置补贴计算公式
        /// </summary>
        /// <value>用于动态计算补贴金额的公式表达式</value>
        [Display(Name = "计算公式", Description = "用于动态计算补贴金额的公式", GroupName = "补贴金额")]
        [MaxLength(512, ErrorMessage = "计算公式长度不能超过512个字符")]
        public string CalculationFormula { get; set; }
        
        /// <summary>
        /// 获取或设置补贴上限金额
        /// </summary>
        /// <value>单次补贴的最大金额限制</value>
        [Display(Name = "上限金额", Description = "单次补贴的最大金额限制", GroupName = "补贴金额")]
        [Range(typeof(decimal), "0", "999999", ErrorMessage = "上限金额必须在0-999999之间")]
        [Column(TypeName = "decimal(8,2)")]
        public decimal? MaxAmount { get; set; }
        
        /// <summary>
        /// 获取或设置补贴下限金额
        /// </summary>
        /// <value>单次补贴的最小金额限制</value>
        [Display(Name = "下限金额", Description = "单次补贴的最小金额限制", GroupName = "补贴金额")]
        [Range(typeof(decimal), "0", "999999", ErrorMessage = "下限金额必须在0-999999之间")]
        [Column(TypeName = "decimal(8,2)")]
        public decimal? MinAmount { get; set; }
        
        // —— 关联班次 ——
        /// <summary>
        /// 
        /// </summary>
        public SysAttendanceShift Shift { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        public Guid? ShiftId { get; set; }
    }

    /// <summary>
    /// 补贴规则类型枚举
    /// </summary>
    /// <remarks>
    /// 定义系统支持的各种补贴类型
    /// </remarks>
    public enum SysSubsidyRuleType
    {
        /// <summary>
        /// 餐补（用餐补贴）
        /// </summary>
        [Display(Name = "餐补")]
        餐补,
        
        /// <summary>
        /// 交通补贴（通勤交通费补贴）
        /// </summary>
        [Display(Name = "交通补贴")]
        交通补贴,
        
        /// <summary>
        /// 加班补贴（加班餐费等补贴）
        /// </summary>
        [Display(Name = "加班补贴")]
        加班补贴,
        
        /// <summary>
        /// 夜班补贴（夜间工作补贴）
        /// </summary>
        [Display(Name = "夜班补贴")]
        夜班补贴,
        
        /// <summary>
        /// 节假日补贴（节假日工作补贴）
        /// </summary>
        [Display(Name = "节假日补贴")]
        节假日补贴,
        
        /// <summary>
        /// 其他补贴（其他类型的补贴）
        /// </summary>
        [Display(Name = "其他补贴")]
        其他补贴
    }
    
    /// <summary>
    /// 补贴计算方式枚举
    /// </summary>
    /// <remarks>
    /// 定义补贴金额的计算方式
    /// </remarks>
    public enum SysSubsidyCalculationType
    {
        /// <summary>
        /// 固定金额（每次发放固定数额的补贴）
        /// </summary>
        [Display(Name = "固定金额")]
        固定金额,
        
        /// <summary>
        /// 按公式计算（根据设定的公式动态计算补贴金额）
        /// </summary>
        [Display(Name = "按公式计算")]
        按公式计算
    }
}
